#include <stdio.h>

/* © 2012 Harry Broeders 
   Uitwerking van opgave 8 van paragraaf 6.18 uit het boek "De programmeertaal C", 4de editie van Kelley en Pohl */

double eval(double p[], double x, int n) {
    int i, j;
    double res = p[0];
    for (i = 1 ; i <= n; i = i + 1) {
        /* bereken x^i */
        double xTotDeMachti = x;
        for (j = 1; j < i; j = j + 1) {
            xTotDeMachti = xTotDeMachti * x;
        }
        res = res + p[i] * xTotDeMachti;
    }
    return res;
}

double evalHorner(double p[], double x, int n) {
    int i;
    double res = p[n];
    for (i = n - 1 ; i >= 0; i = i - 1) {
        res = p[i] + x * res;
    }
    return res;
}

void printErrorAlsOngelijk(double x, double y) {
    /* if (x != y) werkt niet vanwege afrondingsfouten ! */
    double verschil = x - y;
    double absoluutVerschil; 
    if (verschil > 0) {
        absoluutVerschil = verschil;
    }
    else {
        absoluutVerschil = -verschil;
    }
    if (absoluutVerschil >= 1E-10) {
        printf("Error: verwachte waarde = %.10f maar werkelijke waarde is %.10f\n", y, x);
    }
}

int main(void) {
    double p0[] = {-3};                     /* f(x) = -3                                         */
    double p1[] = {4, -4};                  /* f(x) =  4 +   -4*x                                */
    double p2[] = {-2, -1, 1};              /* f(x) = -2 +   -1*x +    1*x^2                     */
    double p3[] = {-2, -1.5, 0.75, 0.25};   /* f(x) = -2 + -1.5*x + 0.75*x^2 +  0.25*x^3         */
    double p4[] = {3, 0.3, -0.5, 6.125, 2}; /* f(x) =  3 +  0.3*x + -0.5*x^2 + 6.125*x^3 + 2*x^4 */
    double y;

    y = eval(p0, 3.2, 0);
    printf("Als f(x) = -3 dan geldt f(3.2) = %f\n", y);
    printErrorAlsOngelijk(y, -3);
    y = eval(p1, 3.2, 1);
    printf("Als f(x) = 4 - 4*x dan geldt f(3.2) = %f\n", y);
    printErrorAlsOngelijk(y, -8.8);
    y = eval(p2, 3.2, 2);
    printf("Als f(x) = -2 - 1*x + x^2 dan geldt f(3.2) = %f\n", y);
    printErrorAlsOngelijk(y, 5.04);
    y = eval(p3, 3.2, 3);
    printf("Als f(x) = -2 - 1.5*x + 0.75*x^2 + 0.25*x^3 dan geldt f(3.2) = %f\n", y);
    printErrorAlsOngelijk(y, 9.072);
    y = eval(p4, 3.2, 4);
    printf("Als f(x) = 3 + 0.3*x - 0.5*x^2 + 6.125*x^3 + 2*x^4 dan geldt f(3.2) = %f\n", y);
    printErrorAlsOngelijk(y, 409.2592);

    y = evalHorner(p0, 3.2, 0);
    printf("Als f(x) = -3 dan geldt f(3.2) = %f\n", y);
    printErrorAlsOngelijk(y, -3);
    y = evalHorner(p1, 3.2, 1);
    printf("Als f(x) = 4 - 4*x dan geldt f(3.2) = %f\n", y);
    printErrorAlsOngelijk(y, -8.8);
    y = evalHorner(p2, 3.2, 2);
    printf("Als f(x) = -2 - 1*x + x^2 dan geldt f(3.2) = %f\n", y);
    printErrorAlsOngelijk(y, 5.04);
    y = evalHorner(p3, 3.2, 3);
    printf("Als f(x) = -2 - 1.5*x + 0.75*x^2 + 0.25*x^3 dan geldt f(3.2) = %f\n", y);
    printErrorAlsOngelijk(y, 9.072);
    y = evalHorner(p4, 3.2, 4);
    printf("Als f(x) = 3 + 0.3*x - 0.5*x^2 + 6.125*x^3 + 2*x^4 dan geldt f(3.2) = %f\n", y);
    printErrorAlsOngelijk(y, 409.2592);

    fflush(stdin);
    getchar();
    return 0;
}